#ifndef STORAGE_STORAGE_H
#define STORAGE_STORAGE_H 1

#include <stdio.h>

#include <common/io.h>
#include <storage/page.h>
#include <storage/itempointer.h>

typedef struct storage_t {
	iohandle_t pages;
	iohandle_t fsm;

	page_size_t page_size;
	int dirty;
} storage_t;

API_LIBLOCAL storage_t *storage_open(const char *, page_size_t);
API_LIBLOCAL void storage_close(storage_t *);

API_LIBLOCAL int storage_remove(const char *);

API_LIBLOCAL int storage_fsm_readlock(storage_t *, page_number_t, page_number_t);
API_LIBLOCAL int storage_fsm_writelock(storage_t *, page_number_t, page_number_t);
API_LIBLOCAL int storage_fsm_unlock(storage_t *, page_number_t, page_number_t);

API_LIBLOCAL int storage_page_readlock(storage_t *, page_number_t);
API_LIBLOCAL int storage_page_writelock(storage_t *, page_number_t);
API_LIBLOCAL int storage_page_rwunlock(storage_t *, page_number_t);

API_LIBLOCAL int storage_page_antivacuumlock(storage_t *, page_number_t);
API_LIBLOCAL int storage_page_vacuumlock(storage_t *, page_number_t);
API_LIBLOCAL int storage_page_vacuumunlock(storage_t *, page_number_t);
API_LIBLOCAL int storage_page_vacuumchecklock(storage_t *, page_number_t);

API_LIBLOCAL int storage_page_read(storage_t *, page_number_t, page_t **);
API_LIBLOCAL int storage_page_write(storage_t *, page_number_t, page_t *);

API_LIBLOCAL int storage_fsm_get_info(storage_t *, page_number_t, page_type_e *, page_size_t *);
API_LIBLOCAL int storage_fsm_lease_new(storage_t *, page_number_t *);
API_LIBLOCAL int storage_fsm_lease_find(storage_t *, page_size_t, page_type_e, page_number_t *, page_number_t *);
API_LIBLOCAL int storage_fsm_lease_return(storage_t *, page_number_t, page_type_e, page_size_t);
API_LIBLOCAL int storage_fsm_update(storage_t *, page_number_t, page_type_e, page_size_t);

API_LIBLOCAL void storage_fsync(storage_t *);

#endif
